﻿using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json.Linq;

namespace BlogsAPI.Sites
{
    using System;
    using System.Text.RegularExpressions;
    using Abstract;
    using System.Diagnostics;
    using System.IO;
    using System.Net;

    /// <summary>
    /// Сервис коротких сообщений на базе ICQ
    /// </summary>
    [BlogServiceAPI(Description = "http://juick.com", IsMicroblog = true)]
    public class Juick : BlogServer
    {
        private static readonly Regex Validation = new Regex(@"^http://(?:\w+\.)?juick\.com", Regexoptions);
        private static readonly Regex ValidationFull = new Regex(@"^http://(?:[-_\w]+\.)?juick\.com/(.*?)(?:/|$)", Regexoptions);
        private static readonly Regex _getAvatar = new Regex(@"<img[^>]+(?:src\W+([^""']+)\W[^>]*?|alt\W+Avatar\W[^>]*?){2}>", Regexoptions);

        #region interface: BlogServer

        /// <summary>
        /// Конструктор!
        /// </summary>
        [DebuggerStepThrough]
        public Juick()
        {
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        public override Boolean ValidateLink(String sLink)
        {
            return Validation.Match(sLink).Success;
        }

        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        public override String GetBlogLink(string userName)
        {
            return String.Format("http://juick.com/{0}", userName);
        }

        /// <summary>
        /// проверка, является ли передаваемый урл чатью этого сервиса
        /// </summary>
        /// <param name="sLink">ссылка для проверки</param>
        /// <param name="userName">Имя пользователя на блогохостинге</param>
        /// <param name="bType">Тип блога - сообщество или блог</param>
        public override Boolean ValidateLink(String sLink, out String userName, out BlogType bType)
        {
            bType = BlogType.Unknown;
            userName = String.Empty;
            Match m = ValidationFull.Match(sLink);
            if (m.Success)
            {
                bType = BlogType.User;
                userName = m.Groups[1].ToString();
            }
            return m.Success;
        }

        /// <summary>
        /// Получение ссылки на блог блогера
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - сообщество или блог</param>
        public override String GetBlogLink(string userName, BlogType btype)
        {
            return GetBlogLink(userName);
        }

        /// <summary>
        /// Извлечение html кода Img аватарки для блога.
        /// </summary>
        /// <param name="userName">ник блогера</param>
        /// <param name="btype">Тип блога - сообщество или блог</param>
        /// <returns></returns>
        public override string ExtractAvatar(string userName, BlogType btype)
        {
            String sRet = String.Empty;
            try
            {
                HttpWebRequest myHttpWebRequest = MakeRequest(GetBlogLink(userName, btype));
                myHttpWebRequest.Method = "GET"; // метод GET
                myHttpWebRequest.Referer = "http://juick.com";
                //получаем ответ и его разбираем...
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                string result = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding).ReadToEnd();
                myHttpWebResponse.Close();
                //ПОЛУЧИЛИ xml - откроемка его...
                Match oRet = _getAvatar.Match(result);
                if (oRet.Success)
                {
                    oRet = _getAvatar.Match(oRet.Groups[0].Value);
                    if (oRet.Success)
                    {
                        sRet = oRet.Groups[1].Value;
                    }
                }
            }
            catch (Exception e1)
            {
                Debug.WriteLine("Ошибка загрузки аватарки блога: " + e1.Message);
            }
            return sRet;
        }

        /// <summary>
        /// Получение ссылки на RSS блогера - берем старым способом... парся страницу целиком
        /// </summary>
        /// <param name="UserName">ник блогера</param>
        /// <remarks>Неработает если имя пользователя русское, тогда нужен номер</remarks>
        public override String GetRssLink(string UserName, BlogType btype)
        {
            return String.Format("http://rss.juick.com/{0}/blog", UserName);
        }

        #endregion


        /// <summary>
        /// Получение списка последних записей
        /// </summary>
        /// <returns>массив постов для индексирования</returns>
        public List<BlogPost> GetLatest(bool onlyrussian = true)
        {
            var oRet = new List<BlogPost>(0);
            try
            {
                HttpWebRequest myHttpWebRequest = MakeRequest("http://api.juick.com/messages");
                myHttpWebRequest.Method = "GET"; // метод GET
                myHttpWebRequest.Referer = "http://api.juick.com";
                //получаем ответ и его разбираем...
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                string result = new StreamReader(myHttpWebResponse.GetResponseStream(), Encoding).ReadToEnd();
                myHttpWebResponse.Close();
                //ПОЛУЧИЛИ JSON - откроемка его...
                JArray data = JArray.Parse(result);
                foreach (JToken jMsg in data)
                {
                    //[{"mid":2064401,"user":{"uid":22802,"uname":"DNB"},"body":"А самоочищающихся клавиатур ещё не придумали?",
                    //"tags":["now","бред","public"],"timestamp":"2012-09-17 09:24:37"} 
                    //"replies": 3
                    string body = jMsg["body"].Value<string>();
                    //http://juick.com/faultcore/2064380
                    if (!String.IsNullOrEmpty(body) && Common.IsRussian(body))
                    {
                        string username = jMsg["user"]["uname"].Value<string>();
                        string tags = String.Empty;
                        if(jMsg["tags"] != null)
                        {
                            tags = jMsg["tags"].Aggregate(tags, (current, tag) => current + (tag + ",")).TrimEnd(',');
                        }

                        BlogPost bp = BlogPost.SimpleLink(String.Format("http://juick.com/{0}/{1}",
                            username, jMsg["mid"].Value<int>()));
                        bp.Comments = jMsg["replies"] == null ? 0 : jMsg["replies"].Value<int>();
                        if(!String.IsNullOrEmpty(tags))
                        {
                            bp.Attributes.Add(new PostAttribute(PostParams.Tags, tags));
                        }
                        bp.Links = 0;
                        bp.SpecialParam = username;
                        bp.Body = body;
                        if (!DateTime.TryParse(jMsg["timestamp"].Value<string>().Replace(" ", "T"),
                                               new CultureInfo("en-US"), DateTimeStyles.AssumeUniversal, out bp.Published))
                        {
                            bp.Published = DateTime.Now;
                        }
                        oRet.Add(bp);
                    }
                }
            }
            catch (Exception e1)
            {
                Debug.Write(e1);
            }
            return oRet;
        }
    }
}